package com.users.rn.common.download

import com.users.rn.common.download.impl.ZipUtils
import com.users.rn.common.init.ALHReactNativeInit
import com.users.rn.common.plugin.PluginHelper
import com.liulishuo.filedownloader.BaseDownloadTask
import com.liulishuo.filedownloader.FileDownloadListener
import com.liulishuo.filedownloader.FileDownloadQueueSet
import com.liulishuo.filedownloader.FileDownloader
import com.liulishuo.filedownloader.model.FileDownloadStatus
import com.users.rn.rncommon.download.ALHPluginDownloadService
import com.users.rn.rncommon.plugin.PluginInformation
import java.io.File

/**

 * 作者：wolf on 1/11/21 14:47

 * 邮箱：bluce

 */

object PluginFileDownloadManager {
    var pluginDownloadListener: ALHPluginDownloadService.PluginDownloadListener? = null
    private val downloadMap: MutableMap<String, BaseDownloadTask> = mutableMapOf()
    private val pluginInQueueSet: MutableMap<String, PluginInformation> = mutableMapOf()

    /**
     * 文件下载监听
     */
    private val downloadListener: FileDownloadListener = object : FileDownloadListener() {
        override fun pending(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
            pluginInQueueSet[task?.tag]?.let {
                pluginDownloadListener?.onComputerTask(task!!.tag as String?, soFarBytes, false, FileDownloadStatus.pending)
            }
        }

        override fun progress(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
            pluginInQueueSet[task?.tag]?.let {
                pluginDownloadListener?.onComputerTask(task!!.tag as String?, soFarBytes * 100 / totalBytes, false, FileDownloadStatus.progress)
            }
        }

        override fun completed(task: BaseDownloadTask?) {
            val pluginName = task?.tag
            val pluginInformation = pluginInQueueSet[pluginName]
            removePluginId(pluginName as String)
            pluginInformation?.let { ZipUtils.unzipPlugin(ALHReactNativeInit.getInitInterface()?.context!!, it, pluginDownloadListener) }
        }

        override fun paused(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
            pluginInQueueSet[task?.tag]?.let {
                pluginDownloadListener?.onComputerTask(task!!.tag as String?, -1, false, FileDownloadStatus.paused)
            }
        }

        override fun error(task: BaseDownloadTask?, e: Throwable?) {
            task?.let { removePluginId(task.tag as String) }
            pluginInQueueSet[task?.tag]?.let {
                pluginDownloadListener?.onComputerTask(task!!.tag as String?, -2, false, FileDownloadStatus.error)
            }
        }

        override fun warn(task: BaseDownloadTask?) {
            pluginInQueueSet[task?.tag]?.let {
                pluginDownloadListener?.onComputerTask(task!!.tag as String?, -3, false, FileDownloadStatus.warn)
            }
        }
    }
    private var queueSet: FileDownloadQueueSet = FileDownloadQueueSet(downloadListener)

    init {
        //失败后，重试1次
        queueSet.setAutoRetryTimes(1)
    }

    fun allTaskFinish(): Boolean {
        return pluginInQueueSet.isEmpty()
    }

    fun addDownloadTasks(pluginInformations: List<PluginInformation>, pluginName: String?): Byte {
        var status = FileDownloadStatus.started
        pluginInformations.forEach {
            val tempStatus = addDownloadTask(it)
            if (it.pluginName == pluginName && tempStatus != null) {
                status = tempStatus
            }
        }
        return status
    }

    /**
     * 添加现在任务
     */
    private fun addDownloadTask(pluginInformation: PluginInformation): Byte? {

        if (!PluginHelper.checkIsLastVersion(pluginInformation)) {
            return FileDownloadStatus.error
        }
        if (downloadMap[pluginInformation.pluginName] != null) {
            return downloadMap[pluginInformation.pluginName]?.status
        }
        ALog.e("sss", "addDownloadTask pluginID:${pluginInformation.pluginName},${ALHReactNativeInit.getInitInterface()?.downloadUrl + pluginInformation.url}")
        pluginInQueueSet[pluginInformation.pluginName] = pluginInformation
        val url = ALHReactNativeInit.getInitInterface()?.downloadUrl + pluginInformation.url
        val task: BaseDownloadTask = FileDownloader.getImpl().create(url)
        val file = File(pluginInformation.fullFilePath)
        if (!file.parentFile.exists()) {
            file.parentFile.mkdirs()
        }
        task.path = pluginInformation.fullFilePath
        task.tag = pluginInformation.pluginName
        downloadMap[pluginInformation.pluginName] = task
        queueSet.downloadTogether(task).start()
        return FileDownloadStatus.pending
    }

    private fun removePluginId(pluginName: String) {
        downloadMap.remove(pluginName)
        pluginInQueueSet.remove(pluginName)
    }

}